home *** CD-ROM | disk | FTP | other *** search
/ Aminet 4 / Aminet 4 - November 1994.iso / aminet / comm / net / dnet_src.lha / dnet / amiga / client / fterm.c < prev    next >
C/C++ Source or Header  |  1990-12-13  |  11KB  |  474 lines

  1.  
  2. /*
  3.  *  FTERM.C
  4.  *
  5.  *  DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
  6.  *
  7.  *  FTERM [-Nnet] [port] [-wcapturefile] [-f<font>.<size>] [-c#]
  8.  *
  9.  *  -c# = cooked mode.    i.e. -c7    bit 0   convert CR's to LF's keyboard->remote
  10.  *                    bit 1   echo chars locally (half duplex)
  11.  *                    bit 2   received LF->CRLF
  12.  *
  13.  *  CHANGING THE WINDOW SIZE UPDATES S:FTERM.CONFIG
  14.  */
  15.  
  16. #include "defs.h"
  17.  
  18. TA Ta = { (ubyte *)"topaz.font", 8 };
  19.  
  20. ITEXT IText[] = {
  21.     { 0, 1, JAM2, 0, 0, &Ta, (ubyte *)"Flush"          },
  22.     { 0, 1, JAM2, 0, 0, &Ta, (ubyte *)"AppendCap"      },
  23.     { 0, 1, JAM2, 0, 0, &Ta, (ubyte *)"NewCap"         },
  24.     { 0, 1, JAM2, 0, 0, &Ta, (ubyte *)"CloseCap"       },
  25.     { 0, 1, JAM2, 0, 0, &Ta, (ubyte *)"Paste"          }
  26.     { 0, 1, JAM2, 0, 0, &Ta, (ubyte *)"FTerm"          }
  27. };
  28.  
  29. ITEM Item[] = {
  30.     { &Item[1], 0, 0, 100, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText[0], NULL, 'o' },
  31.     { &Item[2], 0,10, 100, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText[1], NULL, 'a' },
  32.     { &Item[3], 0,20, 100, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText[2], NULL, 'n' },
  33.     { &Item[4], 0,30, 100, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText[3], NULL, 'c' },
  34.     { &Item[5], 0,40, 100, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText[4], NULL, 'p' },
  35.     { NULL    , 0,50, 100, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText[5], NULL, 'f' }
  36. };
  37.  
  38. MENU Menu[] = {
  39.     { NULL    , 0, 0, 100, 10+50, MENUENABLED, "Control", &Item[0] }
  40. };
  41.  
  42. ubyte Title[80];
  43.  
  44. NW Nw = {
  45.     0, 0, 320, 200, -1, -1,
  46.     NEWSIZE|CLOSEWINDOW|MENUPICK,
  47.     WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|NOCAREREFRESH|ACTIVATE,
  48.     NULL, NULL, Title, NULL, NULL,
  49.     32, 32, -1, -1, WBENCHSCREEN
  50. };
  51.  
  52. char Font[64] = { "topaz.font" };
  53. short FontSize = 8;
  54.  
  55. WIN *Win;
  56.  
  57. extern int Enable_Abort;
  58. char Buf[512];
  59. char Term[64];
  60. char Cc;
  61. char Cooked;    /*  bit 0 = cooked,  bit 1 = local echo */
  62. char IgnoreNS;
  63.  
  64. struct IntuitionBase *IntuitionBase;
  65. struct GfxBase *GfxBase;
  66.  
  67. void OpenConsole ARGS((WIN *, IOCON **, IOCON **));
  68. void HandleIoctl ARGS((short, short, char, WIN *, IOCON *));
  69. void CloseConsole ARGS((IOCON *, IOCON *));
  70. void setsize ARGS((IOCON *, void *, WIN *));
  71. void parseopts ARGS((char *, char **, char **, short *, short *, short *, short *));
  72. void SaveConfig();
  73. void LoadConfig();
  74.  
  75. void main ARGS((int, char **));
  76.  
  77. int
  78. brk()
  79. {
  80.     return(0);
  81. }
  82.  
  83. void
  84. main(ac, av)
  85. char *av[];
  86. {
  87.     void *chan;
  88.     long imask, conmask, dmask, mask;
  89.     IOCON *iocr, *iocw;
  90.     char notdone = 1;
  91.     char portspec = 0;
  92.     char *host = NULL;
  93.     char *capfile = NULL;
  94.     FILE *capfi = NULL;
  95.     uword port = PORT_IALPHATERM;
  96.     FONT *font = NULL;
  97.  
  98.     onbreak(brk);
  99.     sprintf(Title, "FTerm V%s%s", VERSION, FTERM_VERSION);
  100.     strcpy(Term, Title);
  101.     strcat(Title, " opening, wait ...");
  102.  
  103.     {
  104.     char *str = av[0];
  105.     for (str = str + strlen(str); str >= av[0]; --str) {
  106.         if (*str == '/' || *str == ':')
  107.         break;
  108.     }
  109.     ++str;
  110.     if ((*str | 0x20) == 'b')   /*  bbsterm instead of fterm    */
  111.         port = PORT_BBS;
  112.     }
  113.  
  114.     LoadConfig();
  115.  
  116.     {
  117.     short i;
  118.     for (i = 1; i < ac; ++i) {
  119.         char *ptr = av[i];
  120.         if (*ptr == '-') {
  121.         while (*++ptr) {
  122.             switch(*ptr) {
  123.             case 'N':
  124.             host = ptr + 1;
  125.             ptr = "\0";
  126.             break;
  127.             case 'w':
  128.             capfile = ptr + 1;
  129.             ptr = "\0";
  130.             break;
  131.             case 'c':
  132.             Cooked = atoi(ptr + 1);
  133.             ptr = "\0";
  134.             break;
  135.             case 'f':   /*  topaz.8, etc... */
  136.             {
  137.                 char *str;
  138.                 for (str = ptr + 1; *str && *str != '.'; ++str);
  139.                 if (*str == '.') {
  140.                 *str++ = 0;
  141.                 strcpy(Font, ptr);
  142.                 FontSize = atoi(str);
  143.                 }
  144.             }
  145.             break;
  146.             default:
  147.             printf("Unknown option: '%c'\n", *ptr);
  148.             break;
  149.             }
  150.         }
  151.         } else {
  152.         portspec = 1;
  153.         port = atoi(ptr);
  154.         }
  155.     }
  156.     }
  157.     if (capfile)
  158.     capfi = fopen(capfile, "a");
  159.     if (portspec)
  160.     printf("Using port %ld\n", port);
  161. #ifndef LATTICE
  162.     Enable_Abort = 0;
  163. #endif
  164.     IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0);
  165.     GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0);
  166.  
  167.     font = GetFont(Font, FontSize);
  168.  
  169.     Win = OpenWindow(&Nw);
  170.     if (Win == NULL)
  171.     goto e1;
  172.  
  173.     if (font) {
  174.     SetFont(Win->RPort, font);
  175.     SetRast(Win->RPort, 0);
  176.     RefreshWindowFrame(Win);
  177.     }
  178.     OpenConsole(Win, &iocr, &iocw);
  179.     if (iocr == NULL || iocw == NULL)
  180.     goto e3;
  181.  
  182.     /*
  183.      *    We delay here to allow DNET to go through its RESTART sequence
  184.      *    (when DNET automatically runs FTERM, it does so to quickly).
  185.      *    Such a hack!
  186.      */
  187.  
  188.     Delay(50 * 4);
  189.     chan = DOpen(host, port, 20, 15);
  190.  
  191.     if (!chan) {
  192.     puts("Unable to connect");
  193.     goto e3;
  194.     }
  195.     DQueue(chan, 32);
  196.     SetMenuStrip(Win, Menu);
  197.     SetWindowTitles(Win, Term, (char *)-1);
  198.     imask   = 1 << Win->UserPort->mp_SigBit;
  199.     dmask   = 1 << ((PORT *)chan)->mp_SigBit;
  200.     conmask = 1 << iocr->io_Message.mn_ReplyPort->mp_SigBit;
  201.  
  202.     iocr->io_Data = (APTR)&Cc;
  203.     iocr->io_Length = 1;
  204.     SendIO(iocr);
  205.  
  206.     setsize(iocw, chan, Win);
  207.     while (notdone) {
  208.     mask = Wait(imask|dmask|conmask);
  209.     if (mask & imask) {
  210.         IMESS *im;
  211.         while (im = (IMESS *)GetMsg(Win->UserPort)) {
  212.         switch(im->Class) {
  213.         case NEWSIZE:
  214.             Nw.LeftEdge = Win->LeftEdge;
  215.             Nw.TopEdge    = Win->TopEdge;
  216.             Nw.Width    = Win->Width;
  217.             Nw.Height    = Win->Height;
  218.  
  219.             if (IgnoreNS) {
  220.             --IgnoreNS;
  221.             setsize(iocw, NULL, Win);
  222.             } else {
  223.             setsize(iocw, chan, Win);
  224.             }
  225.             break;
  226.         case CLOSEWINDOW:
  227.             notdone = 0;
  228.             break;
  229.         case MENUPICK:
  230.             switch((uword)((MENUNUM(im->Code)<<8)|ITEMNUM(im->Code))) {
  231.             case 0x0000:    /*    menu 0 item 0    */
  232.             DIoctl(chan, CIO_FLUSH, 0, 0);
  233.             break;
  234.             case 0x0001:    /*    menu 0 item 1    */
  235.             if (capfi)
  236.                 fclose(capfi);
  237.             capfi = fopen("ram:capture", "a");
  238.             break;
  239.             case 0x0002:
  240.             if (capfi)
  241.                 fclose(capfi);
  242.             capfi = fopen("ram:capture", "w");
  243.             break;
  244.             case 0x0003:    /*    menu 0 item 2    */
  245.             if (capfi)
  246.                 fclose(capfi);
  247.             capfi = NULL;
  248.             break;
  249.             case 0x0004:    /*    menu 0 item 3    */
  250.             {
  251.                 FILE *fi;
  252.                 long n;
  253.                 if (fi = fopen("ram:paste", "r")) {
  254.                 while ((n = fread(Buf, 1, sizeof(Buf), fi)) > 0) {
  255.                     DWrite(chan, Buf, n);
  256.                 }
  257.                 fclose(fi);
  258.                 }
  259.             }
  260.             break;
  261.             case 0x0005:
  262.             Execute("RUN <NIL: >NIL: fterm", NULL, NULL);
  263.             break;
  264.             case 0x0100:    /*    menu 1 item 0    */
  265.             break;
  266.             }
  267.         }
  268.         ReplyMsg((MSG *)im);
  269.         }
  270.     }
  271.     if (mask & dmask) {
  272.         int n;
  273.         if ((n = DNRead(chan, Buf, sizeof(Buf))) > 0) {
  274.         iocw->io_Data = (APTR)Buf;
  275.         iocw->io_Length = n;
  276.         DoIO(iocw);
  277.         if (capfi)
  278.             fwrite(Buf, n, 1, capfi);
  279.         } else if (n == -2) {
  280.         short val;
  281.         short cmd;
  282.         char aux;
  283.         cmd = DGetIoctl(chan, &val, &aux);
  284.         HandleIoctl(cmd, val, aux, Win, iocw);
  285.         if (cmd == CIO_MODE) {
  286.             if (val)
  287.             SetWindowTitles(Win, "(Cooked)", (char *)-1);
  288.             else
  289.             SetWindowTitles(Win, "(Raw)", (char *)-1);
  290.         }
  291.         } else if (n < 0) {
  292.         notdone = 0;
  293.         }
  294.     }
  295.     if (mask & conmask) {
  296.         if (CheckIO(iocr)) {
  297.         WaitIO(iocr);
  298.         if (Cooked & 2) {       /*  Local Echo  */
  299.             iocw->io_Data = (APTR)&Cc;
  300.             iocw->io_Length = 1;
  301.             DoIO(iocw);
  302.         }
  303.         if ((Cooked & 1) && Cc == 13) {
  304.             Cc = 10;
  305.             iocw->io_Data = (APTR)&Cc;
  306.             iocw->io_Length = 1;
  307.             DoIO(iocw);
  308.         }
  309.         DWrite(chan, &Cc, 1);
  310.         iocr->io_Data = (APTR)&Cc;
  311.         iocr->io_Length = 1;
  312.         SendIO(iocr);
  313.         }
  314.     }
  315.     }
  316.     AbortIO(iocr);
  317.     WaitIO(iocr);
  318.     SetWindowTitles(Win, "Closing...", (char *)-1);
  319.     DClose(chan);
  320. e3: CloseConsole(iocr,iocw);
  321.     if (font) {
  322.     SetFont(Win->RPort, Win->WScreen->RastPort.Font);
  323.     CloseFont(font);
  324.     }
  325.     {
  326.     Nw.LeftEdge = Win->LeftEdge;
  327.     Nw.TopEdge  = Win->TopEdge;
  328.     Nw.Width    = Win->Width;
  329.     Nw.Height   = Win->Height;
  330.  
  331.     SaveConfig();
  332.     }
  333.     CloseWindow(Win);
  334. e1: CloseLibrary((LIB *)IntuitionBase);
  335.     CloseLibrary((LIB *)GfxBase);
  336.     if (capfi)
  337.     fclose(capfi);
  338. }
  339.  
  340. void
  341. OpenConsole(win, piocr, piocw)
  342. IOCON **piocr, **piocw;
  343. WIN *win;
  344. {
  345.     PORT *port;
  346.     static IOCON iocr, iocw;
  347.     int error;
  348.  
  349.     port = CreatePort(NULL, 0);
  350.     iocr.io_Command = CMD_READ;
  351.     iocr.io_Data = (APTR)win;
  352.     iocr.io_Message.mn_Node.ln_Type = NT_MESSAGE;
  353.     iocr.io_Message.mn_ReplyPort = port;
  354.     error = OpenDevice("console.device", 0, &iocr, 0);
  355.     if (!error) {
  356.     iocw = iocr;
  357.     iocw.io_Command = CMD_WRITE;
  358.     *piocr = &iocr;
  359.     *piocw = &iocw;
  360.     } else {
  361.     *piocr = *piocw = NULL;
  362.     }
  363. }
  364.  
  365. void
  366. CloseConsole(iocr, iocw)
  367. IOCON *iocr;
  368. IOCON *iocw;
  369. {
  370.     IOCON *tmp = (iocr) ? iocr : iocw;
  371.     if (tmp) {
  372.     CloseDevice(tmp);
  373.     DeletePort(tmp->io_Message.mn_ReplyPort);
  374.     }
  375. }
  376.  
  377. void
  378. setsize(iocw, chan, win)
  379. IOCON *iocw;
  380. void *chan;
  381. WIN *win;
  382. {
  383.     struct ConUnit *cu = (struct ConUnit *)iocw->io_Unit;
  384.     static char IStr[] = { "\033c\23320l\233t\233u" };
  385.  
  386.     if (Cooked & 4)
  387.     IStr[5] = 'h';
  388.     else
  389.     IStr[5] = 'l';
  390.     iocw->io_Data = (APTR)IStr;
  391.     iocw->io_Length = sizeof(IStr) - 1;
  392.     DoIO(iocw);
  393.     if (chan) {
  394.     DIoctl(chan, CIO_SETROWS, (uword)(cu->cu_YMax+1), 0);
  395.     DIoctl(chan, CIO_SETCOLS, (uword)(cu->cu_XMax+1), 0);
  396.     }
  397.     sprintf(Term, "FTERM   %ld x %ld", cu->cu_YMax+1, cu->cu_XMax+1);
  398.     SetWindowTitles(win, Term, (char *)-1);
  399. }
  400.  
  401. void
  402. HandleIoctl(cmd, val, aux, win, iocw)
  403. short cmd, val;
  404. char aux;
  405. WIN *win;
  406. IOCON *iocw;
  407. {
  408.     static short saverows;
  409.     short height, width;
  410.     short dx, dy;
  411.  
  412.     switch(cmd) {
  413.     case CIO_MODE:
  414.     Cooked = val;
  415.     break;
  416.     case CIO_SETROWS:
  417.     saverows = val;
  418.     break;
  419.     case CIO_SETCOLS:
  420.     width = val * win->RPort->TxWidth + win->BorderLeft + win->BorderRight;
  421.     height= saverows * win->RPort->TxHeight + win->BorderTop + win->BorderBottom;
  422.  
  423.     dx = win->WScreen->Width - (win->LeftEdge + width);
  424.     if (dx > 0)
  425.         dx = 0;
  426.     if (-dx > win->LeftEdge) {
  427.         dx = -win->LeftEdge;
  428.         width = win->WScreen->Width;
  429.     }
  430.  
  431.     dy = win->WScreen->Height - (win->TopEdge + height);
  432.     if (dy > 0)
  433.         dy = 0;
  434.     if (-dy > win->TopEdge) {
  435.         dy = -win->TopEdge;
  436.         height = win->WScreen->Height;
  437.     }
  438.  
  439.     if (dx || dy) {
  440.         MoveWindow(win, dx, dy);
  441.     }
  442.     if (win->Width != width || win->Height != height) {
  443.         SizeWindow(win, width - win->Width, height - win->Height);
  444.         ++IgnoreNS;
  445.     }
  446.     break;
  447.     }
  448. }
  449.  
  450. void
  451. loadConfig()
  452. {
  453.     FILE *fi;
  454.     if (fi = fopen("S:FTerm.config", "r")) {
  455.     fread(&Nw, sizeof(Nw), 1, fi);
  456.     fread(Font, sizeof(Font), 1, fi);
  457.     fread(&FontSize, sizeof(FontSize), 1, fi);
  458.     fclose(fi);
  459.     }
  460. }
  461.  
  462. void
  463. SaveConfig()
  464. {
  465.     FILE *fi;
  466.     if (fi = fopen("S:FTerm.config", "w")) {
  467.     fwrite(&Nw, sizeof(Nw), 1, fi);
  468.     fwrite(Font, sizeof(Font), 1, fi);
  469.     fwrite(&FontSize, sizeof(FontSize), 1, fi);
  470.     fclose(fi);
  471.     }
  472. }
  473.  
  474.